package com.xiaomaoguai.fcp.pre.kepler.router.buf;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xiaomaoguai.fcp.pre.kepler.router.handler.RouterInfo;
import com.xiaomaoguai.fcp.pre.kepler.router.handler.enums.CallBack;
import com.xiaomaoguai.fcp.pre.kepler.router.handler.enums.Instruction;
import com.xiaomaoguai.fcp.pre.kepler.router.utils.GenPipeNumber;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 数据流转容器
 *
 * @author huwenxuan
 * @date 2018/12/25
 */
public class MapBuf implements Buf, Serializable {

	private static final long serialVersionUID = 2447463811960299625L;

	private Map<String, Object> context;

	private String id = GenPipeNumber.getSerialNum();

	private String currentRouterName;

	private String currentHandlerName;

	/**
	 * 远程调用时流程信息
	 */
	private List<RouterInfo> remoteInfos;

	private Boolean rpcBuf = Boolean.FALSE;

	private String nextHandlerName;

	private CallBack callBack = CallBack.NO;

	private Instruction instruction = Instruction.EXCUTE;


	/**
	 * 远程处理异常
	 */
	private Throwable e;

	/**
	 * 异常handlerName
	 */
	private String exceptionHandlerName;

	public MapBuf() {
		context = Maps.newHashMap();
	}

	public MapBuf(Map<String, Object> bufMap) {
		context = bufMap;
	}

	@Override
	public Buf put(String key, Object value) {
		context.put(key, value);
		return this;
	}

	@Override
	public Map<String, Object> getContext() {
		return context;
	}

	@Override
	public Object get(String key) {
		return context.get(key);
	}

	@Override
	public Buf remove(String key) {
		context.remove(key);
		return this;
	}

	@Override
	public void clear() {
		context.clear();
	}

	@Override
	public int size() {
		return context.size();
	}

	@Override
	public Buf object2Buf(Object o) {
		return jsonString2Buf(JSON.toJSONString(o));
	}

	@Override
	public List<RouterInfo> getRemoteInfos() {
		return remoteInfos;
	}

	@Override
	public void setRemoteInfos(List<RouterInfo> remoteInfos) {
		this.remoteInfos = remoteInfos;
	}

	@Override
	public String toString() {
		return toJsonString();
	}

	@Override
	public String toJsonString() {
		return JSON.toJSONString(this);
	}

	@Override
	public Buf jsonString2Buf(String s) {
		try {
			return JSON.parseObject(s, this.getClass());
		} catch (Exception e) {
			return null;
		}
	}

	@Override
	public Buf addRemoteInfo(RouterInfo routerInfo) {
		if (remoteInfos != null) {
			remoteInfos.add(routerInfo);
		} else {
			remoteInfos = Lists.newArrayList(routerInfo);
		}
		return this;
	}

	@Override
	public Buf addRemoteInfo(List<RouterInfo> routerInfos) {
		if (remoteInfos != null) {
			remoteInfos.addAll(routerInfos);
		} else {
			remoteInfos = routerInfos;
		}
		return this;
	}

	@Override
	public void setRpcBuf(boolean rpcBuf) {
		this.rpcBuf = rpcBuf;
	}

	@Override
	public boolean getRpcBuf() {
		return rpcBuf;
	}

	@Override
	public String getNextHandlerName() {
		return nextHandlerName;
	}

	@Override
	public void setNextHandlerName(String nextHandlerName) {
		this.nextHandlerName = nextHandlerName;
	}

	@Override
	public CallBack getCallBack() {
		return callBack;
	}

	@Override
	public void setCallBack(CallBack callBack) {
		this.callBack = callBack;
	}

	@Override
	public Buf setContext(Map<String, Object> context) {
		this.context = context;
		return this;
	}


	@Override
	public String getExceptionHandlerName() {
		return exceptionHandlerName;
	}

	@Override
	public void setExceptionHandlerName(String exceptionHandlerName) {
		this.exceptionHandlerName = exceptionHandlerName;
	}

	@Override
	public Throwable getException() {
		return e;
	}

	@Override
	public void setException(Throwable e) {
		this.e = e;
	}

	@Override
	public String getId() {
		return id;
	}

	@Override
	public void setId(String id) {
		this.id = id;
	}

	@Override
	public String getCurrentRouterName() {
		return currentRouterName;
	}

	@Override
	public String getCurrentHandlerName() {
		return currentHandlerName;
	}

	@Override
	public void setCurrentRouterName(String currentRouterName) {
		this.currentRouterName = currentRouterName;
	}

	@Override
	public void setCurrentHandlerName(String currentHandlerName) {
		this.currentHandlerName = currentHandlerName;
	}

	@Override
	public Instruction getInstruction() {
		return instruction;
	}

	@Override
	public void setInstruction(Instruction instruction) {
		this.instruction = instruction;
	}

}
